package cn.edu.scau.cmi.ema.service;

import cn.edu.scau.cmi.ema.base.CmiPagination;
import cn.edu.scau.cmi.ema.domain.Event;
import cn.edu.scau.cmi.ema.domain.Eventpunish;
import cn.edu.scau.cmi.ema.domain.Punish;
import cn.edu.scau.cmi.ema.service.base.CmiEmaService;
import cn.edu.scau.cmi.ema.util.CmiSqlUtil;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Query;
import java.util.*;
@Service("EventpunishService")
@Transactional

public class EventpunishServiceImpl extends CmiEmaService implements EventpunishService {
	public EventpunishServiceImpl() {
	}

	@Transactional
	public Eventpunish saveEventpunish(Eventpunish eventpunish) {

		if (eventpunish.getId() == null) {
			Event event = eventDAO.findEventById(eventpunish.getEvent().getId());
			Punish punish = punishDAO.findPunishById(eventpunish.getPunish().getId());

			Eventpunish existingEventpunish = eventpunishDAO.findEventpunishByPhysicalPrimaryKey(event.getId(),
					punish.getId(), eventpunish.getDate());

			eventpunish.setEvent(event);
			eventpunish.setPunish(punish);

			if (isEquals(eventpunish, existingEventpunish)) {
				return existingEventpunish;
			}

			eventpunish = eventpunishDAO.store(eventpunish);
			eventpunishDAO.flush();

		} else {
			Eventpunish existingEventpunish = eventpunishDAO.findEventpunishByPrimaryKey(eventpunish.getId());

			eventpunish = eventpunishDAO.store(eventpunish);
			eventpunishDAO.flush();
		}

		return eventpunish;
	}

	public void deleteEventpunish(Eventpunish eventpunish) {
		eventpunishDAO.remove(eventpunish);
		eventpunishDAO.flush();
	}

	@Transactional
	public void deleteEventpunishs(Set<Integer> deleteEventpunishsId) {
		Query query = eventpunishDAO.createNamedQuery("deleteEventpunishsById", -1, -1);
		query.setParameter(1, deleteEventpunishsId);
		query.executeUpdate();
	}

	@Transactional
	public Set<Eventpunish> loadEventpunishs() {
		return eventpunishDAO.findAllEventpunishs();

	}

	@Transactional
	public Set<Eventpunish> loadReferenceEventpunishs(Set<Eventpunish> eventpunishs) {
		Iterator<Eventpunish> eventpunishsIterator = eventpunishs.iterator();
		Set<Eventpunish> referencedEventpunishs = new HashSet<>();
		while (eventpunishsIterator.hasNext()) {
			Eventpunish currentEventpunish = eventpunishsIterator.next();

		}
		return referencedEventpunishs;
	}

	public Set<Eventpunish> loadEventpunishsByIdSet(Set<Integer> eventpunishIdSet) {

		Iterator<Integer> eventpunishIdIterator = eventpunishIdSet.iterator();
		Set<Eventpunish> eventpunishSet = new HashSet<>();
		while (eventpunishIdIterator.hasNext()) {
			Integer id = eventpunishIdIterator.next();
			Eventpunish currentEventpunish = eventpunishDAO.findEventpunishById(id);
			eventpunishSet.add(currentEventpunish);
		}
		return eventpunishSet;
	}

	@Transactional
	public List<Eventpunish> findAllEventpunishs(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Eventpunish>(eventpunishDAO.findAllEventpunishs(startResult, maxRows));
	}

	@Transactional
	public Eventpunish findEventpunishByPrimaryKey(Integer id) {
		return eventpunishDAO.findEventpunishByPrimaryKey(id);
	}

	@Transactional
	public Integer countEventpunishs() {
		return ((Long) eventpunishDAO.createQuerySingleResult("select count(o) from Eventpunish o").getSingleResult())
				.intValue();
	}

	@Transactional
	public Integer countEventpunishs(CmiPagination page) {
		String sql = CmiSqlUtil.createCountHql(page, Eventpunish.class);
		return ((Long) eventpunishDAO.createQuerySingleResult(sql).getSingleResult()).intValue();
	}

	/**
	 * search for name with ajax
	 *
	 */
	@Transactional
	public Integer countEventpunishsByName(String queryName) {
		Query query = eventpunishDAO.createNamedQuery("countEventpunishsByName", -1, -1);
		query.setParameter(1, queryName);
		return new Long((long) query.getSingleResult()).intValue();
	}

	@Transactional
	public Integer countEventpunishsByDetachedCriteria(CmiPagination page) {
		DetachedCriteria detachedCriteria = CmiSqlUtil.createDetachedCriteria(page, Eventpunish.class);
		Session session = (Session) entityManager.getDelegate();
		detachedCriteria.setProjection(Projections.rowCount());
		return new Long((long) detachedCriteria.getExecutableCriteria(session).uniqueResult()).intValue();
	}

	public Map<String, ?> loadEventpunishObjectReferencedSet(Eventpunish eventpunish) {
		HashMap<String, Object> objectReferencedSetMap = new HashMap<>();
		if (eventpunish.getEvent() != null) {

			Set<Integer> eventIds = new HashSet<Integer>();
			eventIds.add(eventpunish.getEvent().getId());
			objectReferencedSetMap.put("eventIds", eventIds);
		}
		if (eventpunish.getPunish() != null) {

			Set<Integer> punishIds = new HashSet<Integer>();
			punishIds.add(eventpunish.getPunish().getId());
			objectReferencedSetMap.put("punishIds", punishIds);
		}

		return objectReferencedSetMap;
	}

	public Map<String, ?> loadEventpunishClassReferencedSet(Eventpunish eventpunish) {
		HashMap<String, Object> classReferencedSetMap = new HashMap<>();
		classReferencedSetMap.put("events", eventDAO.findAllEvents());
		classReferencedSetMap.put("punishs", punishDAO.findAllPunishs());

		return classReferencedSetMap;
	}

	public boolean isEquals(Eventpunish eventpunish, Object obj) {
		if (obj == eventpunish)
			return true;
		if (!(obj instanceof Eventpunish))
			return false;
		Eventpunish comparedEventpunish = (Eventpunish) obj;
		if (!CheckPropertyEqual(eventpunish.getEvent().getId(), comparedEventpunish.getEvent().getId())) {
			return false;
		}
		if (!CheckPropertyEqual(eventpunish.getPunish().getId(), comparedEventpunish.getPunish().getId())) {
			return false;
		}
		if (!CheckPropertyEqual(eventpunish.getDate(), comparedEventpunish.getDate())) {
			return false;
		}
		return true;
	}

	public static <T> boolean CheckPropertyEqual(T originProperty, T comparedProperty) {
		// 基本类型经过参数传递后会自动装箱
		String[] className = originProperty.getClass().getName().split("\\.");
		if (className[0].equals("java") && className[1].equals("math")) {
			return ((Comparable) originProperty).compareTo(comparedProperty) == 0 ? true : false;
		} else {
			return originProperty.equals(comparedProperty);
		}
	}
}

